package cultu.community.service.impl;

import cultu.community.message.Community;
import cultu.community.message.CommunityCriteria;
import cultu.community.message.CommunityList;
import cultu.community.message.CommunityScenario;
import cultu.community.service.CommunityManager;
import cultu.community.service.CommunityService;
import cultu.core.message.JpqlParameter;

/**
 * Community service implementation.
 * @author Marc-Antoine
 *
 */
public class CommunityServiceImpl implements CommunityService
{
  /**
   * The community manager.
   */
  private CommunityManager communityManager;

  /**
   * Sets the community manager.
   *
   * @param communityManager the new community manager
   */
  public void setCommunityManager(CommunityManager communityManager)
  {
    this.communityManager = communityManager;
  }

  /**
   * {@inheritDoc}
   */
  public CommunityList getUniverses(final CommunityScenario cScenario, final CommunityCriteria cCriteria)
  {
    // Query builder.
    final StringBuilder queryBuilder = new StringBuilder("SELECT c FROM Community c WHERE c.familyCode is null ");
    queryBuilder.append("AND c.kindCode is null ");
    queryBuilder.append("AND c.categoryCode is null ");
    queryBuilder.append("AND c.universeCode is not null ");
    queryBuilder.append("ORDER BY c.hjid ASC ");
    
    // Set query to criteria.
    cCriteria.setJpqlQuery(queryBuilder.toString());
    
    return communityManager.findCommunities(null, cScenario, cCriteria);
  }
  
  /**
   * {@inheritDoc}
   */
  public CommunityList getCategories(final Community cUniverse, final CommunityScenario cScenario, final CommunityCriteria cCriteria)
  {
    
    // Query builder.
    final StringBuilder queryBuilder = new StringBuilder("SELECT c FROM Community c WHERE c.familyCode is null ");
    queryBuilder.append("AND c.kindCode is null ");
    queryBuilder.append("AND c.categoryCode is not null ");
    queryBuilder.append("AND c.universeCode is not null ");
    
    
    // If universe is not null, append parameter.
    if (cUniverse != null) {
      queryBuilder.append("AND c.universeCode = :universe ");
    }
    
    queryBuilder.append("ORDER BY c.hjid ASC ");
    
    // Set universe parameter.
    if (cUniverse != null) {
      final JpqlParameter universeParameter = new JpqlParameter();
      universeParameter.setAlias("universe");
      universeParameter.setValue(cUniverse.getUniverseCode());
      
      cCriteria.getParameter().add(universeParameter);  
    }

    // Set query to criteria.
    cCriteria.setJpqlQuery(queryBuilder.toString());

    return communityManager.findCommunities(null, cScenario, cCriteria);
  }
  
  /**
   * {@inheritDoc}
   */
  public Community getUniverseByCode(final String universeCode)
  {
    
    // Criteria.
    final CommunityCriteria cCriteria = new CommunityCriteria();
    
    // Query builder.
    final StringBuilder queryBuilder = new StringBuilder("SELECT c FROM Community c WHERE c.universeCode = :universeCode AND c.categoryCode is null");
        
    final JpqlParameter universeParameter = new JpqlParameter();
    universeParameter.setAlias("universeCode");
    universeParameter.setValue(universeCode);
      
    cCriteria.getParameter().add(universeParameter);  

    // Set query to criteria.
    cCriteria.setJpqlQuery(queryBuilder.toString());

    final CommunityList communityList = communityManager.findCommunities(null, new CommunityScenario(), cCriteria);
    
    if (communityList != null && communityList.getCommunities().size() > 0) {
      return communityList.getCommunities().get(0);
    } else {
      return null;
    }
  }
  
  /**
   * {@inheritDoc}
   */
  public Community getCategoryByCode(final String universeCode, final String categoryCode)
  {
    
    // Criteria.
    final CommunityCriteria cCriteria = new CommunityCriteria();
    
    // Query builder.
    final StringBuilder queryBuilder = new StringBuilder("SELECT c FROM Community c WHERE c.universeCode = :universeCode ");
    queryBuilder.append("AND c.categoryCode = :categoryCode AND c.familyCode is null");
    
    // Universe parameter.
    final JpqlParameter universeParameter = new JpqlParameter();
    universeParameter.setAlias("universeCode");
    universeParameter.setValue(universeCode);
    
    // Category parameter.
    final JpqlParameter categoryParameter = new JpqlParameter();
    categoryParameter.setAlias("categoryCode");
    categoryParameter.setValue(categoryCode);
      
    cCriteria.getParameter().add(universeParameter);
    cCriteria.getParameter().add(categoryParameter); 

    // Set query to criteria.
    cCriteria.setJpqlQuery(queryBuilder.toString());

    final CommunityList communityList = communityManager.findCommunities(null, new CommunityScenario(), cCriteria);
    
    if (communityList != null && communityList.getCommunities().size() > 0) {
      return communityList.getCommunities().get(0);
    } else {
      return null;
    }
  }

  /**
   * {@inheritDoc}
   */
  public CommunityList findRegistrationCommunities(final CommunityScenario cScenario, final CommunityCriteria cCriteria) {

    // Query builder.
    final StringBuilder queryBuilder = new StringBuilder("SELECT c FROM Community c WHERE c.familyCode is null ");
    queryBuilder.append("AND c.kindCode is null ");
    queryBuilder.append("AND (c.categoryCode is not null OR c.universeCode is not null )");
    queryBuilder.append("ORDER BY c.universeCode ASC, c.categoryCode DESC ");

    // Set query to criteria.
    cCriteria.setJpqlQuery(queryBuilder.toString());

    return communityManager.findCommunities(null, cScenario, cCriteria);
  }
  
  /**
   * {@inheritDoc}
   */
  public CommunityList findAllCommunities(final CommunityScenario cScenario, final CommunityCriteria cCriteria) {
    
    // Query builder.
    final StringBuilder queryBuilder = new StringBuilder("SELECT c FROM Community c");

    // Set query to criteria.
    cCriteria.setJpqlQuery(queryBuilder.toString());

    return communityManager.findCommunities(null, cScenario, cCriteria);
  }
}
